#include "MyForm.h"
#include <QtDebug>
#include <QStandardItemModel>
#include <QFileDialog>
#include <QErrorMessage>
#include <QDragEnterEvent>
#include <QTextStream>
#include <QMimeData>
#include <QFileInfo>
#include "pluginslist.h"
#include "queueArea.h"
#include "PluginsInterface.h"



MyForm::MyForm(QWidget *parent)
	: MyFormBase(parent),
	errorMessage(new ErrorMessage(this))

{
	addImageStratum = new addImagePluginStratum(this);
	allPlugins = new pluginsList(this, Config, addImageStratum);
	freedesktopMime = new QFreeDesktopMime(this, ":/FreedesktopMime/freedesktop.org.xml");
	queue = ui.queue;
	this->setAcceptDrops(true);

	this->restoreGeometry(Config->value("geometry").toByteArray());
	ui.splitter->restoreState(Config->value("splitter").toByteArray());
	ui.splitter_2->restoreState(Config->value("splitter_2").toByteArray());
	ui.splitter_3->restoreState(Config->value("splitter_3").toByteArray());

	pluginsTable = new AboutPlugins(ui.pluginsTableView);

	connect(ui.buttonAboutQt, SIGNAL(clicked()), qApp, SLOT(aboutQt()));
	connect(addImageStratum, SIGNAL(addMyWidget(QWidget*)), this, SLOT(addImagePluginWidget(QWidget*)));
	connect(addImageStratum, SIGNAL(addImage(QString)), this, SLOT(setPreview(QString)));
	connect(&trans, SIGNAL(retranslateUi()), allPlugins, SLOT(retranslatePlugins()));

	loadPlugins();
}

MyForm::~MyForm()
{
	allPlugins->deleteLater();
}

void MyForm::addImagePluginWidget(QWidget *widget) // insert widget for getting images
{
	ui.stackedWidget->removeWidget(ui.defaultPage);
	ui.stackedWidget->addWidget(widget);
}

void MyForm::setPreview(QString filename)
{
	qDebug() << filename;
	QFile *file = new QFile(filename);
	if ( ! file->exists() ) {
		errorMessage->showMessage("File not exist\n"+file->fileName());
		return;
	}
	setPreview(file, QFileInfo(file->fileName()).fileName()); // QFile auto downgraded to QIODevice here
}

void MyForm::setPreview(QIODevice *file, QString name)
{
	if (!file->isOpen()) {
		if (!file->open(QIODevice::ReadOnly)) {
			qWarning() << tr("make preview:") << "can't read image" << name
							<< "(" << file->errorString() << ")";
			errorMessage->showMessage(name + " is not a file or I just can't read it");
			return;
		}
	} else {
		if ( !file->reset() ) {
			errorMessage->showMessage(name + ": file is opened, but I can't seek to beginning");
			return;
		}
	}
	QString mime = freedesktopMime->fromDevice(file);
	if ( mime.isEmpty() ) {
		qDebug() << "can't get correct mime type. Will try filename";
		mime = freedesktopMime->fromFileName(name);
		if ( mime.isEmpty() ) {
			qWarning() << "really can't get file mime-format";
		}
	}
#if DEBUG_MIME
	qDebug() << "Image name:" << name << "mime format:" << mime;
	return;
#endif
	PreviewWidget *preview = new PreviewWidget(this, file, name, mime);
	queue->addPreview(preview);
}

void MyForm::dragEnterEvent(QDragEnterEvent *event) const
{
	const QMimeData *mimeData = event->mimeData();
	if ( mimeData->hasFormat("text/uri-list") )
	{
		foreach ( QUrl draggedFile, mimeData->urls() )
			if ( draggedFile.scheme() != "file" )
				return;
		event->acceptProposedAction();
	}
}

void MyForm::dropEvent(QDropEvent *event)
{
	if (event->mimeData()->hasFormat("text/uri-list"))
	{
		foreach ( QUrl file, event->mimeData()->urls() ) {
			if ( file.scheme() == "file" )
				setPreview(file.toLocalFile());
			else
				qWarning() << file.toString() << "sheme is not supported for now";
		}
	}
}

void MyForm::loadPlugins()
{
	if ( allPlugins->loadPlugins() ) {
//		ui.UploadButton->setEnabled(true);
//		ui.actionStart->setEnabled(true);
	}
	if ( ui.toolBox->count() > Config->value("currentSettingsTab").toInt() ) {
		ui.toolBox->setCurrentIndex(Config->value("currentSettingsTab").toInt());
	}
}

void MyForm::enableUploadButton(const bool enable) {
	if ( (enable && allPlugins->countOfUploadPlugins() > 0) ||
	     !enable) {
		ui.UploadButton->setEnabled(enable);
		ui.actionStart->setEnabled(enable);
	}
}

void MyForm::disableUploadButton(const bool disable) {
	enableUploadButton(!disable);
}

void MyForm::upload()
{
	if(queue->isEmpty())
		return;
	if(!allPlugins->getCurrentPlugin()) {
		qDebug() << "Please, select one hosting before trying to upload images";
		errorMessage->showMessage("Please, select one hosting before trying to upload images");
		return;
	}
	currentUploading = 0;
	Stratum = new signalSlotStratum(this);
	ui.uploadProcessBar->setFormat("%p% Completed");
	ui.uploadProcessBar->setAlignment(Qt::AlignHCenter);
	ui.uploadProcessBar->setRange(0, 100);
	ui.uploadProcessBar->setValue(0);
	ui.uploadProcessBar->setVisible(true);
	connect(Stratum, SIGNAL(totalError(QString)), this, SLOT(onTotalError(QString)));
	connect(Stratum, SIGNAL(fileUploadFailed(int,QString)), this, SLOT(onFileUploadFailed(int,QString)));
	connect(Stratum, SIGNAL(uploadComplete(QList<UploadResult>)),
			this, SLOT(onUploadComplete(QList<UploadResult>)));
	connect(Stratum, SIGNAL(updateStatus(int,int)), this, SLOT(updateCurrentProgress(int,int)));
	connect(Stratum, SIGNAL(updateStatus(int,int,int)), this, SLOT(updateCurrentProgress(int,int,int)));
	connect(Stratum, SIGNAL(startNextFile(int)), this, SLOT(startNextFile(int)));
	connect(Stratum, SIGNAL(fileUploaded(int, UploadResult)), this, SLOT(fileUploaded(int, UploadResult)));
	connect(ui.CancelButton, SIGNAL(clicked()), Stratum, SIGNAL(cancelUpload()));
	connect(ui.CancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));

	ui.UploadButton->setEnabled(false);
	ui.actionStart->setEnabled(false);
	ui.CancelButton->setEnabled(true);
	ui.actionCancel->setEnabled(true);
	queue->lockRemoveButtons();

	QList<ImageToUpload> ImagesToUpload = queue->ImagesToUpload();
	allPlugins->getCurrentPlugin()->startUpload(ImagesToUpload, Stratum);
}

void MyForm::onTotalError(const QString &errorMessage)
{
	qWarning() << errorMessage;
	queue->setUploadError(currentUploading, errorMessage);
}

void MyForm::onFileUploadFailed(const int index, const QString &errorMessage)
{
	qWarning() << index << errorMessage;
	queue->setUploadError(index, errorMessage);
}

void MyForm::setResultLabelText() const
{
	QString newText;
	bool html = Config->value("useHtml", true).toBool();
	foreach (const UploadResult fileResult, LastUploadResult) {
		newText += historyWidget::resultText(fileResult,
				Config->value(html ? "resTemplateHtml" : "resTemplatePlain").toString(),
				html);
	}
	ui.resultLabel->setText(newText);
	ui.resultLabel->setTextFormat( html ? Qt::RichText : Qt::PlainText );
	if ( Config->value("autoCopy", true).toBool() ) {
		QString clipboardText;
		foreach (const UploadResult fileResult, LastUploadResult)
			clipboardText += historyWidget::resultText(fileResult,
					Config->value("resTemplatePlain").toString(),
					false);
		qApp->clipboard()->setText(clipboardText);
	}
}

void MyForm::onUploadComplete(const QList<UploadResult> &uploadResult)
{
	LastUploadResult = uploadResult;
	setResultLabelText();

	disconnect(Stratum, SIGNAL(totalError(QString)), this, SLOT(onTotalError(QString)));
	disconnect(Stratum, SIGNAL(uploadComplete(QList<UploadResult>)),
			this, SLOT(onUploadComplete(QList<UploadResult>)));
	disconnect(ui.CancelButton, SIGNAL(clicked()), Stratum, SIGNAL(cancelUpload()));
	ui.uploadProcessBar->setVisible(false);
	queue->unlockRemoveButtons();
	Stratum->deleteLater();
	bool allUploaded = true;
	foreach ( const UploadResult res, uploadResult )
	{
		qDebug() << "Result success:" << res.success << "for image:" << res.index;
		if ( res.success )
		{
			queue->setToDelete(res.index, true);
			historyWidget *histPiece = new historyWidget(
#ifndef NOPREVIEW
				*queue->previewPxm(res.index),
#endif //NOPREVIEW
				res.ImageName, res );
			ui.historyArea->addHistWidget(histPiece);
		} else
			allUploaded = false;
	}
	queue->removeFinished();
	if (Config->value("uploadedTab", false).toBool() and allUploaded)
		ui.tabWidget->setCurrentWidget(ui.uploadedTab);
	ui.dontClearQueue->setChecked(ui.dontClearQueuePref->isChecked());
	ui.CancelButton->setEnabled(false);
	ui.actionCancel->setEnabled(false);
	if ( !queue->isEmpty() ) {
		ui.UploadButton->setEnabled(true);
		ui.actionStart->setEnabled(true);
	}
}

void MyForm::startNextFile(const int index)
{
	if ( queue->count() > index ) {
		currentUploading = index;
		queue->started(index);
	}
}

void MyForm::fileUploaded(const int index, const UploadResult &result) {
	Q_UNUSED(result);
	queue->finished(index);
}

void MyForm::onCancel()
{
/* // Do I really need this function?
	if ( currentUploading != 0 ) {
		currentUploading->uploadCanceled();
		uploadedSize += currentUploading->size;
	}
*/
}

void MyForm::updateCurrentProgress(int value, int max)
{ updateCurrentProgress(value, max, currentUploading); }

void MyForm::updateCurrentProgress(int value, int max, int index)
{
	if ( index ) {
		queue->setProgress(value, max, index);
		ui.uploadProcessBar->setMaximum(ui.queue->totalSize());
		ui.uploadProcessBar->setValue(ui.uploadProcessBar->value()+ui.queue->lastDelta(index));
	} else {
		ui.uploadProcessBar->setMaximum(max);
		ui.uploadProcessBar->setValue(value);
	}
}

